﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using Kooboo.HtmlFunc.Function;
using Kooboo.HtmlFunc.Providers;

namespace Kooboo.HtmlFunc.Analysis.Visitors
{
    public class ListVisitor : StartEndVisitor
    {
        public ListVisitor(VisitorContext context)
            : base(context, FuncType.List)
        {
        }

        private IFuncTester _startCommentTester;
        protected override IFuncTester StartCommentTester
        {
            get
            {
                if (_startCommentTester == null)
                    _startCommentTester = new Testers.ParametricTester(this.Func.StartComment);
                return _startCommentTester;
            }
        }

        protected override object OnQualified(HtmlCommentNode startNode, HtmlCommentNode endNode)
        {
            var tester = (Testers.ParametricTester)this.StartCommentTester;
            var folderName = tester.GetParameter("folder");
            if (string.IsNullOrEmpty(folderName))
            {
                if (!this.Context.ThrowException)
                    return null;
                throw new Exceptions.ParameterEmptyException(this.Context.FileName, startNode, "folder");
            }

            int? pageSize = null;
            int intPageSize = 0;
            if (int.TryParse(tester.GetParameter("pageSize"), out intPageSize))
                pageSize = intPageSize;

            int? takeTop = null;
            int intTakeTop = 0;
            if (int.TryParse(tester.GetParameter("takeTop"), out intTakeTop))
                takeTop = intTakeTop;

            // owner layout position
            int? order = null;
            IPosition ownerPosition = null;
            if (this.Context.Items.ContainsKey(FuncType.Position))
            {
                ownerPosition = (IPosition)this.Context.Items[FuncType.Position];
                order = ownerPosition.ChildCount++;
            }

            // add
            var list = Provider.Factory.GetProvider<IList>();
            list.ViewName = this.GetListViewName(tester.GetParameter("viewName"), folderName);
            list.FolderName = folderName;
            list.PageSize = pageSize;
            list.TakeTop = takeTop;
            list.OrderBy = tester.GetParameter("orderBy");
            list.OrderByDescending = tester.GetParameter("orderByDescending");
            list.StartNode = startNode;
            list.EndNode = endNode;
            list.Order = order;
            list.OwnerPosition = ownerPosition;
            this.Context.Result.Lists.Add(list);

            // ret context mark
            return list;
        }

        private string GetListViewName(string viewName, string folderName)
        {
            if (!string.IsNullOrEmpty(viewName))
                return viewName;

            var count = this.Context.Result.Lists.Count(o => o.FolderName.IgnoreCaseEquals(folderName));
            var subfix = (count == 0) ? string.Empty : count.ToString();
            return folderName + "_list" + subfix;
        }

        protected override FuncType ExclusiveType
        {
            get
            {
                return this.FuncType
                    | FuncType.Menu
                    | FuncType.Label
                    | FuncType.HtmlBlockPart
                    | FuncType.HtmlPart
                    | FuncType.ViewPart
                    | FuncType.Detail;
            }
        }
    }
}
